﻿using System;
using System.Collections.Generic;
using System.Text;

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

  /// <summary>
    /// JSON传输结果类
    /// </summary>
    public class JsonTransfer
    {
        private Dictionary<string, object> _dict = new Dictionary<string,object>();
        private string _errorKey = "error";
        private string _contentKey = "content";

        /// <summary>
        /// 
        /// </summary>
        public JsonTransfer()
        {
            
        }

        /// <summary>
        /// 默认追加到_contentKey里
        /// </summary>
        /// <param name="content"></param>
        public JsonTransfer(object content)
        {
            Add(_contentKey, content);
        }

        /// <summary>
        /// 追加响应键值对,value必须是可以序列化的对象
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public JsonTransfer Add(string key, object value)
        {
            //dict[key] = value;
            if (value == null) //如果value=null，则不再输出到客户端
                return Remove(key);
            else
            {
                bool added = false;

                if (string.IsNullOrEmpty(key)) //如果key为空，而且 value 是字典的话，就把字典对象
                {
                    Dictionary<string, object> tempDict = value as Dictionary<string, object>;
                    if (tempDict != null)
                    {
                        added = true;

                        // 枚举并显示所有的键/值对.
                        foreach (KeyValuePair<string, object> kvp in tempDict)
                        {
                            if (!_dict.ContainsKey(kvp.Key))
                                _dict.Add(kvp.Key, kvp.Value);
                        }
                    }
                }

                if (!added)
                    _dict[key] = value;
            }
            return this;
        }

        /// <summary>
        /// 增加一个字典对象，其中只保留指定的key，如果specifiedKeys=*，则全部保留
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dict"></param>
        /// <param name="specifiedKeys"></param>
        /// <returns></returns>
        public JsonTransfer Add(string key, Dictionary<string, object> dict, string specifiedKeys)
        {
            if (specifiedKeys == "*")
                return Add(key, dict);
            else
            {
                Dictionary<string, object> dictToAdd = new Dictionary<string, object>();
                string[] keys = specifiedKeys.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string specKey in keys)
                {
                    string realKey = specKey.Trim();//健壮性考虑
                    object value = null;
                    if (dict.TryGetValue(realKey, out value))
                    {
                        if (value != null)
                            dictToAdd.Add(realKey, value);
                    }
                }

                return Add(key, dictToAdd);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public JsonTransfer Remove(string key)
        {
            _dict.Remove(key);

            return this;
        }

        /// <summary>
        /// 如果isJson=true，则直接添加一个json字符串到输出里，以json的形式输出
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="isJson"></param>
        /// <returns></returns>
        public JsonTransfer Add(string key, string value, bool isJson)
        {
            if (isJson)
                _dict[key] = new RawJsonString(value);
            else
                _dict[key] = value;
            return this;
        }

        /// <summary>
        /// 增加错误键
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public JsonTransfer SetError(object value)
        {
            return Add(_errorKey, value);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public JsonTransfer ClearError()
        {
            //if (dict.ContainsKey(_errorKey))
            _dict.Remove(_errorKey);
            return this;
        }

        /// <summary>
        /// 清空所有已经添加的对象
        /// </summary>
        public void Clear()
        {
            _dict.Clear();
        }

        /// <summary>
        /// 结果以JSON格式输出
        /// </summary>
        /// <returns></returns>
        public string ToJson()
        {
            return ToJson(_dict);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJson(object obj)
        {
            return ToJson(obj, false, true);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="indented"></param>
        /// <param name="ignoreNull"></param>
        /// <returns></returns>
        public static string ToJson(object obj, bool indented, bool ignoreNull)
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();
            if (ignoreNull)
            {
                settings.NullValueHandling = NullValueHandling.Ignore;
                settings.MissingMemberHandling = MissingMemberHandling.Ignore;
                settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                settings.DefaultValueHandling = DefaultValueHandling.Ignore;
            }

            settings.Converters.Add(new RawJsonStringConverter(typeof(RawJsonString)));
            settings.Converters.Add(new IsoDateTimeConverter());

            return JsonConvert.SerializeObject(obj, indented ? Formatting.Indented : Formatting.None, settings);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string SerializeObject(object obj)
        {
            return ToJson(obj);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T DeserializeObject<T>(string value)
        {
            return JsonConvert.DeserializeObject<T>(value);
        }

        /// <summary>
        /// 重写tostring方法
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return ToJson();
        }
    }
